﻿#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "libs.h"
#include "webui.h"

static struct file_link list_head;
static char chapter_titles[1024 * 1024];
//list_only = 1, only get chapter list
int mobi_convert(char* buf, int size, char* stitle, char* author, char* regex, int list_only);


const char kindle_previewer[] = "https://www.amazon.com/gp/feature.html?docId=1000765261";
const char mac_link_cmd[] = 
	"ln -s /Applications/Kindle\\ Previewer\\ 3.app/Contents/lib/fc/bin/kindlegen \
/usr/local/bin/kindlegen";

void printf_info(void)
{
	printf("convert txt file to mobi format\n");
	printf("mac: please download \"Kindle Previewer\" from \n %s\n", kindle_previewer);
	printf("mac: specified the kindlegen path\n");
	//printf("  windows: Kindle Previewer install dir \n \
	//	\\lib\\fc\\bin\\kindlegen.exe \n");
	printf("  mac: \n%s\n", mac_link_cmd);
	printf("app tested under kindlegen V2.9\n");

	printf("\n\n");
	printf("please ensure txt file is UTF-8 charset\n");
	printf("start to convert \n");
}

long get_file_size(FILE* fp)
{
	long size;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	//restore file pointer
	fseek(fp, 0, SEEK_SET);

	return size;
}

void mk_dirs(void)
{
	system("powershell -Command \"del -r temp\""); //deltet temp\ directory
	system("mkdir temp");
	system("xcopy /s /i META-INF temp\\META-INF");
	system("xcopy /s /i OEBPS temp\\OEBPS");
	system("copy mimetype temp");
}

void fill_chapter_titles(char* buf, struct file_link* head)
{
	struct file_link* cur;
	char* temp = buf;
	size_t len = 0;

	list_for_each_entry(cur, &head->list, list, struct file_link) {
		strcpy(temp, cur->chapter_name);
		len = len + strlen(cur->chapter_name);
		buf[len] = '\n'; //append next chapter
		len++;
		buf[len] = 0;
		temp = buf + len;
	}
}

/*
	convert 

middle files:
	toc: book-toc.html, toc.ncx
	cover: cover.html
	style: style.css
	opf: content.opf
chapter files:
chapter1.html chapter3.html chapter5.html ...

output mobi:
	kindlegen content.opf
*/
int txt2mobi(char *buf, long size, char* title)
{
	int ret = 0;
	init_list(&list_head, size);
	ret = build_toc(buf, size, &list_head);
	if (ret) {
		destroy_list(&list_head);
		return -2;
	}
	fill_chapter_titles(chapter_titles, &list_head);

	gen_book_id();

	mk_dirs();
	//book-toc.html, toc.ncx
	output_book_toc(buf, title, &list_head);
	output_cover(buf, title);
	output_ncx(buf, title, &list_head);
	output_opf(buf, title, &list_head);
	output_html(buf, title, &list_head);

	destroy_list(&list_head);
	output_mobi(title);
	return 0;
}

int get_chapters_list(char* buf, long size)
{
	int ret = 0;
	init_list(&list_head, size);
	ret = build_toc(buf, size, &list_head);
	if (ret) {
		destroy_list(&list_head);
		return -2;
	}
	fill_chapter_titles(chapter_titles, &list_head);
	destroy_list(&list_head);
	return 0;
}

void close_app(webui_event_t* e)
{
	printf("Exit.\n");

	// Close all opened windows
	webui_exit();
}

//JavaScript: list_chapters_call_c(contents, file_size, title, author, regex, flag)
void list_chapters_call_c(webui_event_t* e)
{
	char* content = (char*)webui_get_string_at(e, 0);
	int size = (int)webui_get_int_at(e, 1);
	char* title = (char*)webui_get_string_at(e, 2);
	char* author = (char*)webui_get_string_at(e, 3);
	char* regex = (char*)webui_get_string_at(e, 4);
	int flag = (int)webui_get_int_at(e, 5);

	set_novel_author(author);

	int ret = mobi_convert(content, size, title, author, regex, flag);
	// Send back the response to JavaScript
	if (ret < 0) {
		webui_return_string(e, "不能生成章节列表\n请检查正则表达式");
	} else {
		if(flag == 1)
			webui_return_string(e, chapter_titles);
		else
			webui_return_string(e, "转换完成");
	}
}

void webui_init(void)
{
	// Create a new window
	size_t MainWindow = webui_new_window();

	// Set the root folder for the UI
	//webui_set_root_folder(MainWindow, ".");

	// Bind HTML elements with the specified ID to C functions
	webui_bind(MainWindow, "close_app", close_app);
	webui_bind(MainWindow, "list_chapters_call_c", list_chapters_call_c);

	// Show the window, preferably in a chromium based browser
	if (!webui_show_browser(MainWindow, "txt2mobi.html", AnyBrowser))
		webui_show(MainWindow, "txt2mobi.html");

	// Wait until all windows get closed
	webui_wait();
	// Free all memory resources (Optional)
	webui_clean();
}

int mobi_convert(char* buf, int size, char* stitle, char* author, char* regex, int list_only)
{
	int ret = 0;
	set_novel_name(stitle);

	int utf = 0;
	utf = text_charset(buf, size);
	set_charset(utf);

	default_regex_str = regex;
	char* content = buf;
	int realsize = size;

	char* utf_content = NULL;
	if (!utf) {
		//to utf-8
		utf_content = to_utf(buf, size, &realsize);
		if (!utf_content)
			return -2;
		content = utf_content;
	}

	//main process
	if (list_only) {
		ret = get_chapters_list(content, realsize);
	}
	else {
		ret = txt2mobi(content, realsize, stitle);
	}

	if (!utf) {
		free(utf_content);
	}

	return ret;
}

void init_date_time(void)
{
	time_t current_time;
	struct tm* local_time;
	char time_str[20];

	set_novel_date(2021);
	current_time = time(NULL);
	if (current_time == -1) {
		fprintf(stderr, "Failed to get current time.\n");
		return;
	}

	local_time = localtime(&current_time);
	if (local_time == NULL) {
		fprintf(stderr, "Failed to convert to local time.\n");
		return;
	}

	if (strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", local_time) == 0) {
		fprintf(stderr, "Failed to format time.\n");
		return;
	}

	printf("current time %s\n", time_str);
	unsigned int year = local_time->tm_year + 1900;
	set_novel_date(year);
}

int main(int argc, char** argv)
{
	init_date_time();
	webui_init();
	return 0;
}
